package me.flyray.bsin.server.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.extern.slf4j.Slf4j;
import me.flyray.bsin.context.BsinServiceContext;
import me.flyray.bsin.domain.entity.ChainSettlementAccount;
import me.flyray.bsin.domain.request.SettlementAccountDTO;
import me.flyray.bsin.facade.service.ChainSettlementAccountService;
import me.flyray.bsin.infrastructure.mapper.ChainSettlementAccountMapper;
import me.flyray.bsin.security.contex.LoginInfoContextHelper;
import me.flyray.bsin.security.domain.LoginUser;
import me.flyray.bsin.server.utils.Pagination;
import org.apache.commons.collections4.MapUtils;
import org.apache.shenyu.client.apache.dubbo.annotation.ShenyuDubboService;
import org.apache.shenyu.client.apidocs.annotations.ApiDoc;
import org.apache.shenyu.client.apidocs.annotations.ApiModule;
import org.apache.shenyu.client.dubbo.common.annotation.ShenyuDubboClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;

@ShenyuDubboService(path = "/chainSettlementAccount", timeout = 6000)
@ApiModule(value = "chainSettlementAccount")
@Service
@Slf4j
public class ChainSettlementAccountServiceImpl implements ChainSettlementAccountService {

    @Autowired
    private ChainSettlementAccountMapper chainSettlementAccountMapper;

    @ShenyuDubboClient("/setUp")
    @ApiDoc(desc = "setUp")
    @Override
    public void setUp(Map<String, Object> requestMap) {
        LoginUser loginUser = LoginInfoContextHelper.getLoginUser();
        log.info("添加结算账户请求参数: {}, 登录用户: {}", requestMap, loginUser);
        
        ChainSettlementAccount account = BsinServiceContext.getReqBodyDto(ChainSettlementAccount.class, requestMap);
        
        // 设置租户ID和创建人
        if (account.getTenantId() == null) {
            account.setTenantId(loginUser.getTenantId());
        }
        if (account.getCreateBy() == null) {
            account.setCreateBy(loginUser.getCustomerNo());
        }
        
        // 设置默认状态
        if (account.getStatus() == null) {
            // 默认待审核
            account.setStatus("1");
        }
        if (account.getDefaultFlag() == null) {
            account.setDefaultFlag("1");
        }
        account.setBizRoleType(loginUser.getBizRoleType());
        account.setBizRoleTypeNo(loginUser.getBizRoleTypeNo());
        account.setDelFlag("0");
        
        // 如果是第一个账户，自动设为默认
        Long count = chainSettlementAccountMapper.selectCount(new LambdaQueryWrapper<ChainSettlementAccount>()
                .eq(ChainSettlementAccount::getDelFlag, "0")
                .eq(ChainSettlementAccount::getTenantId, loginUser.getTenantId()));
        if (count == 0) {
            account.setDefaultFlag("1");
        }
        
        // 如果设置新默认，需要将其他账户设为非默认
        if ("1".equals(account.getDefaultFlag())) {
            chainSettlementAccountMapper.update(null, new LambdaUpdateWrapper<ChainSettlementAccount>()
                    .set(ChainSettlementAccount::getDefaultFlag, "0")
                    .set(ChainSettlementAccount::getUpdateTime, LocalDateTime.now())
                    .eq(ChainSettlementAccount::getDelFlag, "0")
                    .eq(ChainSettlementAccount::getTenantId, loginUser.getTenantId()));
        }
        
        chainSettlementAccountMapper.insert(account);
        log.info("添加结算账户成功，ID: {}", account.getSerialNo());
    }

    @ShenyuDubboClient("/edit")
    @ApiDoc(desc = "edit")
    @Override
    public void edit(Map<String, Object> requestMap) {
        LoginUser loginUser = LoginInfoContextHelper.getLoginUser();
        log.info("编辑结算账户请求参数: {}, 登录用户: {}", requestMap, loginUser);
        
        ChainSettlementAccount account = BsinServiceContext.getReqBodyDto(ChainSettlementAccount.class, requestMap);
        
        // 检查账户是否存在
        ChainSettlementAccount existAccount = chainSettlementAccountMapper.selectById(account.getSerialNo());
        if (existAccount == null || "1".equals(existAccount.getDelFlag())) {
            throw new IllegalArgumentException("账户不存在或已删除");
        }
        
        // 设置更新人
        account.setUpdateBy(loginUser.getCustomerNo());
        
        chainSettlementAccountMapper.updateById(account);
        log.info("编辑结算账户成功，ID: {}", account.getSerialNo());
    }

    @ShenyuDubboClient("/delete")
    @ApiDoc(desc = "delete")
    @Override
    public void delete(Map<String, Object> requestMap) {
        LoginUser loginUser = LoginInfoContextHelper.getLoginUser();
        String serialNo = MapUtils.getString(requestMap, "serialNo");
        log.info("删除结算账户请求参数: {}, 登录用户: {}", requestMap, loginUser);
        
        ChainSettlementAccount account = chainSettlementAccountMapper.selectById(serialNo);
        if (account == null || "1".equals(account.getDelFlag())) {
            throw new IllegalArgumentException("账户不存在或已删除");
        }
        
        // 检查是否为默认账户
        if ("1".equals(account.getDefaultFlag())) {
            throw new IllegalArgumentException("默认账户不能删除");
        }
        
        // 逻辑删除
        account.setDelFlag("1");
        account.setUpdateBy(loginUser.getCustomerNo());
        
        chainSettlementAccountMapper.updateById(account);
        log.info("删除结算账户成功，ID: {}", serialNo);
    }

    @ShenyuDubboClient("/getDetail")
    @ApiDoc(desc = "getDetail")
    @Override
    public ChainSettlementAccount getDetail(Map<String, Object> requestMap) {
        String serialNo = MapUtils.getString(requestMap, "serialNo");
        log.info("获取结算账户详情请求参数: {}", requestMap);
        
        ChainSettlementAccount account = chainSettlementAccountMapper.selectById(serialNo);
        return account;
    }

    @ShenyuDubboClient("/getList")
    @ApiDoc(desc = "getList")
    @Override
    public List<ChainSettlementAccount> getList(Map<String, Object> requestMap) {
        ChainSettlementAccount account = BsinServiceContext.getReqBodyDto(ChainSettlementAccount.class, requestMap);
        log.info("获取结算账户列表请求参数: {}", requestMap);
        
        LambdaQueryWrapper<ChainSettlementAccount> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.orderByDesc(ChainSettlementAccount::getCreateTime);
        queryWrapper.eq(ChainSettlementAccount::getDelFlag, "0");
        queryWrapper.eq(ChainSettlementAccount::getTenantId, LoginInfoContextHelper.getTenantId());
        
        // 根据条件筛选
        queryWrapper.eq(ObjectUtil.isNotNull(account.getCategory()), ChainSettlementAccount::getCategory, account.getCategory());
        queryWrapper.eq(ObjectUtil.isNotNull(account.getAccountType()), ChainSettlementAccount::getAccountType, account.getAccountType());
        queryWrapper.eq(ObjectUtil.isNotNull(account.getStatus()), ChainSettlementAccount::getStatus, account.getStatus());
        queryWrapper.like(ObjectUtil.isNotNull(account.getAccountName()), ChainSettlementAccount::getAccountName, account.getAccountName());
        queryWrapper.eq(ObjectUtil.isNotNull(account.getAccountNum()), ChainSettlementAccount::getAccountNum, account.getAccountNum());
        
        return chainSettlementAccountMapper.selectList(queryWrapper);
    }

    @ShenyuDubboClient("/getPageList")
    @ApiDoc(desc = "getPageList")
    @Override
    public IPage<ChainSettlementAccount> getPageList(Map<String, Object> requestMap) {
        ChainSettlementAccount account = BsinServiceContext.getReqBodyDto(ChainSettlementAccount.class, requestMap);
        Object paginationObj = requestMap.get("pagination");
        Pagination pagination = new Pagination();
        if (paginationObj != null) {
            BeanUtil.copyProperties(paginationObj, pagination);
        } else {
            // 如果没有分页对象，使用默认参数
            pagination.setPageNum(1);
            pagination.setPageSize(10);
        }
        
        Page<ChainSettlementAccount> page = new Page<>(pagination.getPageNum(), pagination.getPageSize());
        
        LambdaQueryWrapper<ChainSettlementAccount> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.orderByDesc(ChainSettlementAccount::getCreateTime);
        queryWrapper.eq(ChainSettlementAccount::getDelFlag, "0");
        queryWrapper.eq(ChainSettlementAccount::getTenantId, LoginInfoContextHelper.getTenantId());
        
        // 根据条件筛选
        queryWrapper.eq(ObjectUtil.isNotNull(account.getCategory()), ChainSettlementAccount::getCategory, account.getCategory());
        queryWrapper.eq(ObjectUtil.isNotNull(account.getAccountType()), ChainSettlementAccount::getAccountType, account.getAccountType());
        queryWrapper.eq(ObjectUtil.isNotNull(account.getStatus()), ChainSettlementAccount::getStatus, account.getStatus());
        queryWrapper.like(ObjectUtil.isNotNull(account.getAccountName()), ChainSettlementAccount::getAccountName, account.getAccountName());
        queryWrapper.eq(ObjectUtil.isNotNull(account.getAccountNum()), ChainSettlementAccount::getAccountNum, account.getAccountNum());
        queryWrapper.eq(ObjectUtil.isNotNull(account.getDefaultFlag()), ChainSettlementAccount::getDefaultFlag, account.getDefaultFlag());
        
        IPage<ChainSettlementAccount> pageList = chainSettlementAccountMapper.selectPage(page, queryWrapper);
        return pageList;
    }
    
    // 设置默认账户的额外方法
    @ShenyuDubboClient("/setDefault")
    @ApiDoc(desc = "setDefault")
    public void setDefault(Map<String, Object> requestMap) {
        LoginUser loginUser = LoginInfoContextHelper.getLoginUser();
        String serialNo = MapUtils.getString(requestMap, "serialNo");
        log.info("设置默认结算账户请求参数: {}, 登录用户: {}", requestMap, loginUser);
        
        ChainSettlementAccount account = chainSettlementAccountMapper.selectById(serialNo);
        if (account == null || "1".equals(account.getDelFlag())) {
            throw new IllegalArgumentException("账户不存在或已删除");
        }
        
        // 先将同一租户的所有账户设为非默认
        chainSettlementAccountMapper.update(null, new LambdaUpdateWrapper<ChainSettlementAccount>()
                .set(ChainSettlementAccount::getDefaultFlag, "0")
                .set(ChainSettlementAccount::getUpdateTime, LocalDateTime.now())
                .eq(ChainSettlementAccount::getDelFlag, "0")
                .eq(ChainSettlementAccount::getTenantId, loginUser.getTenantId()));
        
        // 设置当前账户为默认
        account.setDefaultFlag("1");
        account.setUpdateBy(loginUser.getCustomerNo());
        
        chainSettlementAccountMapper.updateById(account);
        log.info("设置默认结算账户成功，ID: {}", serialNo);
    }

}
